package com.sikaryofficial.backend.manager.store;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.sikaryofficial.backend.constant.RedisCacheKey;
import com.sikaryofficial.backend.domain.dto.req.store.StoreSearchCountReq;
import com.sikaryofficial.backend.domain.dto.resp.StoreListDTO;
import com.sikaryofficial.backend.domain.entity.SearchLog;
import com.sikaryofficial.backend.domain.entity.Store;
import com.sikaryofficial.backend.domain.entity.StoreSearchResultItem;
import com.sikaryofficial.backend.service.ISearchLogService;
import com.sikaryofficial.backend.service.IStoreSearchResultItemService;
import com.sikaryofficial.backend.service.IStoreService;
import com.sikaryofficial.common.redis.service.RedisService;
import com.sikaryofficial.common.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.Async;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author : qinjinyuan
 * @desc :  搜索关键字统计
 * @date : 2025/08/21 11:37
 */
@Slf4j
@SuppressWarnings(value = "unchecked")
public class SearchKeywordManager {
    @Autowired
    private ISearchLogService searchLogService;
    @Autowired
    private IStoreSearchResultItemService resultItemService;
    @Autowired
    private IStoreService storeService;
    @Autowired
    private RedisService redisService;
    private static final Long SECURITY_DEFAULT_USER_ID = 0L;
    /**
     * ✅ 正确理解：全局统计（All Users）
     *
     * @param req
     */
    @Async("asyncTaskExecutor")
    public void searchCount(StoreSearchCountReq req) {
        Long userId = SecurityUtils.getUserId();
        if (Objects.isNull(userId) || SECURITY_DEFAULT_USER_ID.equals(userId)) {
            // 未登录用户，不统计阅读量
            log.info("用户未登录（userId: {}），不记录店铺阅读量", userId);
            return;
        }
        // 1. 构建缓存key
        String cacheKey = buildSearchCountKey(req);
        if (Boolean.TRUE.equals(redisService.hasKey(cacheKey))) {
            return;
        }
        // 2. 搜索关键词统计数据处理
        processCountData(req);
        // 3. 缓存设置（数据防刷）
        redisService.setCacheObject(cacheKey, System.currentTimeMillis(), 2L, TimeUnit.MINUTES);
    }

    private String buildSearchCountKey(StoreSearchCountReq req) {
        // 搜索关键词全局统计缓存
        String md5Value = DigestUtil.md5Hex(SecurityUtils.getUserId().toString() + "_"
                + req.getKeyword()
        );
        return MessageFormat.format(RedisCacheKey.STORE_SEARCH_COUNT_CACHE, md5Value);
    }

    /**
     * ✅ 批量处理数据
     *
     * @param req
     */
    private void processCountData(StoreSearchCountReq req) {
        SearchLog searchLog = searchLogService.lambdaQuery()
                .eq(SearchLog::getKeyword, req.getKeyword())
                .orderByDesc(SearchLog::getCreatedTime).last(" limit 1").one();
        if (Objects.isNull(searchLog)) {
            searchLog = SearchLog.builder().keyword(req.getKeyword()).createdBy(SecurityUtils.getUserId())
                    .createdTime(new Date()).build();
            searchLogService.save(searchLog);
        }
        List<Store> storeList = storeService.lambdaQuery().likeRight(Store::getStoreName, req.getKeyword()).list();
        if (CollUtil.isEmpty(storeList)) {
            return;
        }
        // 3. 批量记录搜索结果中的店铺
        List<StoreSearchResultItem> items = new ArrayList<>();
        for (Store shop : storeList) {
            StoreSearchResultItem item = new StoreSearchResultItem();
            item.setResultItemId(IdWorker.getId());
            item.setSearchLogId(searchLog.getSearchLogId());
            item.setStoreId(shop.getStoreId());
            item.setStoreName(shop.getStoreName());
            // 排名从1开始
            item.setRankInResults(1);
            item.setCreatedBy(SecurityUtils.getUserId());
            items.add(item);
        }
        resultItemService.batchInsertOrUpdate(items);
    }

    public List<StoreListDTO> recommendTop8() {

        // 获取推荐分数最高的前8个店铺
        // 如果需要获取分数信息，使用扩展方法
        Set<ZSetOperations.TypedTuple<String>> top8WithScores = redisService.getReverseCacheZSetWithScores(RedisCacheKey.STORE_RECOMMEND_Z_SET_KEY, 0, 7);
        if (CollUtil.isEmpty(top8WithScores)) {
            return new ArrayList<>();
        }
        // 提取店铺ID列表
        List<String> storeIds = top8WithScores.stream()
                .map(ZSetOperations.TypedTuple::getValue)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (CollUtil.isEmpty(storeIds)) {
            return new ArrayList<>();
        }

        // 查询店铺基本信息
        List<Store> storeList = storeService.lambdaQuery()
                .select(Store::getStoreId, Store::getStoreName)
                .in(Store::getStoreId, storeIds)
                .list();

        // 构建店铺ID到店铺信息的映射
        Map<Long, Store> storeMap = storeList.stream()
                .collect(Collectors.toMap(Store::getStoreId, s -> s));

        // 按分数从高到低排序并转换为DTO
        return storeIds.stream()
                .map(storeIdStr -> {
                    Long storeId = Long.valueOf(storeIdStr);
                    Store store = storeMap.get(storeId);
                    if (store != null) {
                        StoreListDTO dto = new StoreListDTO();
                        dto.setStoreId(store.getStoreId());
                        dto.setStoreName(store.getStoreName());
                        return dto;
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
}
